STM32 SDIO 挂载 FATFS读写TF卡

您所在的位置:网站首页 Stm32 tf卡读写 STM32 SDIO 挂载 FATFS读写TF卡

STM32 SDIO 挂载 FATFS读写TF卡

2024-07-09 02:44| 来源: 网络整理| 查看: 265

参考文章 以下的内容可能需要参考文章 USB重定向printf STM32 SDIO 读写 TF卡 使用FatFs文件系统读写SD卡

CubeMX配置

在fatfs中勾选SD Card选项 在这里插入图片描述

代码分析

实现几个函数 创建app_flie_operate.c函数

#include "app_flie_operate.h" #include "usbd_cdc_if.h" // 定义用于格式化的工作区缓存 BYTE workBuffer[4 * User_Sector]; /*挂载FatFs文件系统*/ void Mount_FatFs(void) { // 挂载文件系统 FRESULT retUSER = f_mount(&User_FatFs, User_SDPath, 1); // 发生错误 if (retUSER != FR_OK) { // 没有文件系统,需要格式化 if (retUSER == FR_NO_FILESYSTEM) { usb_printf("\r\nNo file system, start formatting\r\n"); // 创建文件系统 retUSER = f_mkfs(User_SDPath, FM_FAT32, 0, workBuffer, 4 * User_Sector); // 格式化失败 if (retUSER != FR_OK) { usb_printf("Formatting failed, error code = %d \r\n", retUSER); } // 格式化成功 else { usb_printf("The formatting is successful, and the mounting starts again\r\n"); // 有文件系统后重新挂载 retUSER = f_mount(&User_FatFs, User_SDPath, 1); // 挂载失败 if (retUSER != FR_OK) { usb_printf("Error occurred. Error code = %d \r\n", retUSER); } // 挂载成功 else { usb_printf("*** The file system is mounted successfully ***\r\n"); } } } // 不是没有文件系统,而是发生其他错误 else { usb_printf("Another error occurred, error code = %d \r\n", retUSER); } } // 有文件系统直接挂在成功 else { usb_printf("The file system is mounted successfully\r\n"); } } /*获取磁盘信息并在LCD上显示*/ void FatFs_GetDiskInfo(void) { FATFS *fs; // 定义剩余簇个数变量 DWORD fre_clust; // 获取剩余簇个数 FRESULT res = f_getfree("0:", &fre_clust, &fs); // 获取失败 if (res != FR_OK) { usb_printf("f_getfree() error\r\n"); return; } usb_printf("\r\n*** FAT disk info ***\r\n"); // 总的扇区个数 DWORD tot_sect = (fs->n_fatent - 2) * fs->csize; // 剩余的扇区个数 = 剩余簇个数 * 每个簇的扇区个数 DWORD fre_sect = fre_clust * fs->csize; // 对于SD卡和U盘, _MIN_SS=512字节 #if _MAX_SS == _MIN_SS // SD卡的_MIN_SS固定为512,右移11位相当于除以2048 // 剩余空间大小,单位:MB,用于SD卡,U盘 DWORD freespace = (fre_sect >> 11); // 总空间大小,单位:MB,用于SD卡,U盘 DWORD totalSpace = (tot_sect >> 11); #else // Flash存储器,小容量 // 剩余空间大小,单位:KB DWORD freespace = (fre_sect * fs->ssize) >> 10; // 总空间大小,单位:KB DWORD totalSpace = (tot_sect * fs->ssize) >> 10; #endif // FAT类型 usb_printf("FAT type = %d\r\n", fs->fs_type); usb_printf("[1=FAT12,2=FAT16,3=FAT32,4=exFAT]\r\n"); // 扇区大小,单位字节 usb_printf("Sector size(bytes) = "); // SD卡固定512字节 #if _MAX_SS == _MIN_SS usb_printf("%d\r\n", _MIN_SS); #else // FLASH存储器 usb_printf("%d\r\n", fs->ssize); #endif usb_printf("Cluster size(sectors) = %d\r\n", fs->csize); usb_printf("Total cluster count = %ld\r\n", fs->n_fatent - 2); usb_printf("Total sector count = %ld\r\n", tot_sect); // 总空间 #if _MAX_SS == _MIN_SS usb_printf("Total space(MB) = %ld\r\n", totalSpace); #else usb_printf("Total space(KB) = %ld\r\n", totalSpace); #endif // 空闲簇数量 usb_printf("Free cluster count = %ld\r\n", fre_clust); // 空闲扇区数量 usb_printf("Free sector count = %ld\r\n", fre_sect); // 空闲空间 #if _MAX_SS == _MIN_SS usb_printf("Free space(MB) = %ld\r\n", freespace); #else usb_printf("Free space(KB) = %ld\r\n", freespace); #endif usb_printf("Get FAT disk info OK\r\n"); } /*创建文本文件*/ void FatFs_WriteTXTFile(TCHAR *filename, uint16_t year, uint8_t month, uint8_t day) { FIL file; usb_printf("\r\n*** Creating TXT file: %s ***\r\n", filename); FRESULT res = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE); // 打开/创建文件成功 if (res == FR_OK) { // 字符串必须有换行符"\n" TCHAR str[] = "Line1: Hello, FatFs***\n"; // 不会写入结束符"\0" f_puts(str, &file); usb_printf("Write file OK: %s\r\n", filename); } else { usb_printf("Open file error,error code: %d\r\n", res); } // 使用完毕关闭文件 f_close(&file); } /*读取一个文本文件的内容*/ void FatFs_ReadTXTFile(TCHAR *filename) { usb_printf("\r\n*** Reading TXT file: %s ***\r\n", filename); FIL file; // 以只读方式打开文件 FRESULT res = f_open(&file, filename, FA_READ); // 打开成功 if (res == FR_OK) { // 读取缓存 TCHAR str[100]; // 没有读到文件内容末尾 while (!f_eof(&file)) { // 读取1个字符串,自动加上结束符”\0” f_gets(str, 100, &file); usb_printf("%s", str); } usb_printf("\r\n"); } // 如果没有该文件 else if (res == FR_NO_FILE) usb_printf("File does not exist\r\n"); // 打开失败 else usb_printf("f_open() error,error code: %d\r\n", res); // 关闭文件 f_close(&file); } /*扫描和显示指定目录下的文件和目录*/ void FatFs_ScanDir(const TCHAR *PathName) { DIR dir; // 目录对象 FILINFO fno; // 文件信息 // 打开目录 FRESULT res = f_opendir(&dir, PathName); // 打开失败 if (res != FR_OK) { // 关闭目录,直接退出函数 f_closedir(&dir); usb_printf("\r\nf_opendir() error,error code: %d\r\n", res); return; } usb_printf("\r\n*** All entries in dir: %s ***\r\n", PathName); // 顺序读取目录中的文件 while (1) { // 读取目录下的一个项 res = f_readdir(&dir, &fno); // 文件名为空表示没有多的项可读了 if (res != FR_OK || fno.fname[0] == 0) break; // 如果是一个目录 if (fno.fattrib & AM_DIR) { usb_printf("DIR: %s\r\n", fno.fname); } // 如果是一个文件 else { usb_printf("FILE: %s\r\n", fno.fname); } } // 扫描完毕,关闭目录 usb_printf("Scan dir OK\r\n"); f_closedir(&dir); } /*获取一个文件的文件信息*/ void FatFs_GetFileInfo(TCHAR *filename) { usb_printf("\r\n*** File info of: %s ***\r\n", filename); FILINFO fno; // 检查文件或子目录是否存在 FRESULT fr = f_stat(filename, &fno); // 如果存在从fno中读取文件信息 if (fr == FR_OK) { usb_printf("File size(bytes) = %ld\r\n", fno.fsize); usb_printf("File attribute = 0x%x\r\n", fno.fattrib); usb_printf("File Name = %s\r\n", fno.fname); // 输出创建/修改文件时的时间戳 FatFs_PrintfFileDate(fno.fdate, fno.ftime); } // 如果没有该文件 else if (fr == FR_NO_FILE) usb_printf("File does not exist\r\n"); // 发生其他错误 else usb_printf("f_stat() error,error code: %d\r\n", fr); } /*删除文件*/ void FatFs_DeleteFile(TCHAR *filename) { usb_printf("\r\n*** Delete File: %s ***\r\n", filename); FIL file; // 打开文件 FRESULT res = f_open(&file, filename, FA_OPEN_EXISTING); if (res == FR_OK) { // 关闭文件 f_close(&file); usb_printf("open successfully!\r\n"); } // 删除文件 res = f_unlink(filename); // 删除成功 if (res == FR_OK) { usb_printf("The file was deleted successfully!\r\n"); } // 删除失败 else { usb_printf("File deletion failed, error code:%d\r\n", res); } } /*打印输出文件日期*/ void FatFs_PrintfFileDate(WORD date, WORD time) { usb_printf("File data = %d/%d/%d\r\n", ((date >> 9) & 0x7F) + 1980, (date >> 5) & 0xF, date & 0x1F); usb_printf("File time = %d:%d:%d\r\n", (time >> 11) & 0x1F, (time >> 5) & 0x3F, time & 0x1F); }

创建app_flie_opreate.h

#ifndef __APP_FILE_OPERATE_H__ #define __APP_FILE_OPERATE_H__ #include "main.h" #include "FatFs.h" #include "stdio.h" /*定义自己的存储设备*/ /*用户存储设备扇区字节数*/ #define User_Sector 4096 /*用户存储设备FatFS对象*/ #define User_FatFs SDFatFS /*用户存储设备卷路径*/ #define User_SDPath SDPath /*函数声明*/ void Mount_FatFs(void); void FatFs_GetDiskInfo(void); void FatFs_ScanDir(const TCHAR *PathName); void FatFs_ReadTXTFile(TCHAR *filename); void FatFs_WriteTXTFile(TCHAR *filename, uint16_t year, uint8_t month, uint8_t day); void FatFs_GetFileInfo(TCHAR *filename); void FatFs_DeleteFile(TCHAR *filename); void FatFs_PrintfFileDate(WORD date, WORD time); #endif

创建以下函数

/** * @brief SD卡文件系统测试 * @param */ void SD_FATFS_TEST_Task(void ) { HAL_Delay(5000); HAL_StatusTypeDef status; status = HAL_SD_Init(&hsd1); /* 初始化 */ if(status != HAL_OK) { usb_printf("SD card initialize failed!\n"); while(1) { HAL_Delay(1000); usb_printf("SD card initialize failed!\n"); } } HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&hsd1); if(state == HAL_SD_CARD_TRANSFER) { HAL_SD_GetCardCID(&hsd1, &SD_CardCID); usb_printf("\nInitialize SD card sucessfully!\r\n"); usb_printf("\nSD card information\r\n"); usb_printf("\nCapacity :%llu\r\n", ((unsigned long long)hsd1.SdCard.BlockSize*hsd1.SdCard.BlockNbr)); usb_printf("\nBlockSize :%d\r\n", hsd1.SdCard.BlockSize); usb_printf("\nRCA :%d\r\n", hsd1.SdCard.RelCardAdd); usb_printf("\nCardType :%d\r\n", hsd1.SdCard.CardType); usb_printf("\nManufacturerID :%d\r\n", SD_CardCID.ManufacturerID); } else { usb_printf("\nSD card initialize failed.\n"); } Mount_FatFs(); while (1) { /*按键1被按下*/ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { HAL_Delay(50); if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET) { FatFs_ScanDir("0:/"); while (!HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)) ; } } /*按键KEY2被按下*/ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { HAL_Delay(50); if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET) { FatFs_WriteTXTFile("test.txt", 2024, 5, 30); while (!HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)) ; } } /*按键KEY3被按下*/ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET) { HAL_Delay(50); if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET) { FatFs_ReadTXTFile("test.txt"); FatFs_GetFileInfo("test.txt"); while (!HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin)) ; } } } }

在main.c文件中调用

实验结果

在这里插入图片描述 显示挂载成功



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3